//
//  ViewController.m
//  内存管理综合
//
//  Created by ZhouFahong on 17/3/21.
//  Copyright © 2017年 ZhouFahong. All rights reserved.
/*
 Xcode5之后，新建iOS工程，默认都是ARC模式，但是有时候我们的项目中需要用到一些第三方框架，我们下载下来却发现是非ARC的，这时候我们需要进行ARC和MRC混编。
 第1种方式，Edit->Refactor，转换成ARC方式。
 第2种方式，给编译器加标记。 *******
 可以在Build Phases中的Compile Sources中加入编译标记-fno-objc-arc，确实可行，但是文件好多，这种方式适合文件比较少的情况，文件多了难道我们要一个一个加嘛，这 时候我们可以借助一个工具xproj，这是一个脚本，可以很方便的给某个文件夹内的文件添加编译标记，具体使用方法我们看项目主页就行了，既可以给ARC 项目添加MRC标记（-fno-objc-arc），也可以给MRC项目添加ARC标记（-fobjc-arc）。
 
 第3种方式，打包成静态库。
 最后一种方式，就是项目引用。新建一个项目，改为非ARC，在另一个项目中引用这个项目，我们需要把项目B中的无关文件删除掉，自己重写成ARC方式。
*/

/*
 autorelease  相当于C语言中的自动变量（局部变量）
 局部变量，如不作专门说明为静态变量，都是动态分配存储空间，存储在动态存储区中。这种变量叫自动变量。这种变量只在定义它们的时候才创建，在定义它们的函数返回时系统回收变量所占存储空间。对这些变量存储空间的分配和回收是由系统自动完成的，所以也叫自动变量。一般情况下，不作专门说明的局部变量，均是自动变量。
*/
#import "ViewController.h"
#import "Person.h"
#import "SecondViewController.h"

int global_val = 1;

static int static_global_val = 30;

@interface ViewController ()

@property(nonatomic,strong)NSString *hugPerson;

@end

@implementation ViewController

@dynamic viewTest;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self dispatchGroup];
    
    int __block a=9;
    const char *text = "zhou";
    
    void (^bbb)(void)=^{
        a=11;
        global_val = 22;
        static_global_val = 88;
        NSLog(@"Hello world!");
        NSLog(@" a = %d\n",static_global_val);
        printf("text[2] = %c\n",text[2]);
    };
    
    bbb();
    
//    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
    
    
    Person *person = [Person new];
    [person autorelease];
    
    NSLog(@"retainCount = %lu",(unsigned long)[person retainCount]);
    [person study];
    
    [self eatWithPerson:person];
//    _objc_autoreleasePoolPrint();
    
//    [person retain];
//    NSLog(@"retainCount = %lu",(unsigned long)[person retainCount]);
//    [person release];
//    NSLog(@"retainCount = %lu",(unsigned long)[person retainCount]);
    [self addButton];
    /*［array addObject:obj];
     　这样obj的引用计数会增加1，
       如果使用remove则obj的引用计数会减一。
     */
    NSMutableArray *array = [NSMutableArray array] ;
    [array addObject:person];
    NSLog(@"retainCount = %lu",(unsigned long)[person retainCount]);
    [array addObject:person];
    NSLog(@"retainCount = %lu",(unsigned long)[person retainCount]);
//    [pool drain];
}
-(void)viewWillAppear:(BOOL)animated{
    NSArray *arr =  self.navigationController.viewControllers;
    for (UIViewController *ctr in arr) {
        NSLog(@"===============");
        NSLog(@"%@",NSStringFromClass([ctr class]));
    }
}

-(void)addButton{
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    [button setFrame:CGRectMake(55, 80, 55, 55)];
    [button setTitle:@"push" forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:button];
    [button addTarget:self action:@selector(pushToSecondViewController) forControlEvents:UIControlEventTouchUpInside];
}
-(void)pushToSecondViewController{
    SecondViewController *ctr = [[SecondViewController alloc]init];
    [self.navigationController pushViewController:ctr animated:YES];
}
-(void)eatWithPerson:(Person*)person{
    [person eat];
}

-(void)dealloc{
    
    self.viewTest = nil;
    
    [super dealloc];
}

#pragma mark ------------ GCD -------------

-(void)dispatchGroup{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_queue_t queue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"queue0");
    });
    dispatch_group_async(group, queue1, ^{
        NSLog(@"queue1");
    });
    dispatch_group_async(group, queue2, ^{
        NSLog(@"queue2");
    });
    dispatch_group_async(group, queue3, ^{
        NSLog(@"queue3");
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"done!!!!!");
    });
    dispatch_release(group);
    
    [self dispath];
}

/*
 由 NSDate 类对象获取能传递给 dispatch_after 函数的 dispatch_time_t 类型的值
 */
dispatch_time_t getDispatchTimeByDate(NSDate *date){
    NSTimeInterval interval;
    double second,subsecond;
    struct timespec time;
    dispatch_time_t milestone;
    interval = [date timeIntervalSince1970];
    subsecond = modf(interval, &second); // modf() 将浮点数分解为整数和小数部分
    time.tv_sec = second;
    time.tv_nsec = subsecond * NSEC_PER_SEC;
    
    // dispatch_walltime函数 用于计算绝对时间
    milestone = dispatch_walltime(&time, 0);
    return milestone;
}

-(void)dispath{
    dispatch_queue_t dis = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(dis, ^{
        
        NSLog(@"queeeeee ...");
        
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"main ...");
        });
        
        // 3秒后执行处理
        dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull + NSEC_PER_SEC);
        dispatch_after(time, dispatch_get_main_queue(), ^{
            NSLog(@"3s after ...");
        });
        time = getDispatchTimeByDate([NSDate date]);
        
        // 3秒后执行处理
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"NSDate after ...2222");
        });
        
    });
}


@end
/*
 
 */
